#pragma ident "$Id XY. CAO 2017-08-27 $"

/**
* @file SppCheck.hpp
* This is a class to compute initial value of receiver clock offset 
* and check the code observations( with receiver position known).
* 
*/

#ifndef GPSTK_SPPCHECK_HPP
#define GPSTK_SPPCHECK_HPP

//============================================================================
//  
// Warning: used after BasicModel.
// This class is very convinient to extend to normal case when the
// receiver coordinate is unknown.
//
//  XY CAO, Wuhan University, 2017 
//============================================================================



#include "ProcessingClass.hpp"
#include "EphemerisRange.hpp"
#include "EngEphemeris.hpp"
#include "XvtStore.hpp"
#include "GPSEphemerisStore.hpp"


namespace gpstk
{
	/** @addtogroup GPSsolutions */
	//@{

	/** This is a class to compute the basic parts of a GNSS model, like
	*  geometric distance, relativity correction, satellite position and
	*  velocity at transmission time, satellite elevation and azimuth, etc.
	*
	* This class is intended to be used with GNSS Data Structures (GDS).
	* It is a more modular alternative to classes such as ModelObs
	* and ModelObsFixedStation.
	*
	* A typical way to use this class follows:
	*
	* @code
	*      // Input observation file stream
	*   RinexObsStream rin("ebre0300.02o");
	*
	*      // Load the precise ephemeris file
	*   SP3EphemerisStore sp3Eph;
	*   sp3Eph.loadFile("igs11513.sp3");
	*
	*      // Reference position of receiver station
	*   Position nominalPos(4833520.2269, 41537.00768, 4147461.489);
	*
	*      // Some more code and definitions here...
	*
	*   gnssRinex gRin;  // GNSS data structure for fixed station data
	*
	*      // Set defaults of models. A typical P1-based modeling is used
	*   BasicModel model( nominalPos, sp3Eph );
	*   SppCheck spp;
	*
	*   while(rin >> gRin)
	*   {
	*
	*         // Apply the model on the GDS
	*      gRin >> model >> spp;
	*   }
	*
	* @endcode
	*
	* The "SppCheck" object will visit every satellite in
	* the GNSS data structure that is "gRin" and will try to compute
	* its model: Geometric distance, relativity delay, satellite position
	* at transmission time, satellite elevation and azimuth, etc.
	*
	* When used with the ">>" operator, this class returns the same
	* incoming data structure with the extra data inserted along their
	* corresponding satellites. Be warned that if a given satellite does
	* not have ephemeris information, it will be summarily deleted
	* from the data structure.
	*
	*/
	class SppCheck : public ProcessingClass
	{
	public:

		/// Default constructor. Observable C1 will be used for computations
		/// and satellites with elevation less than 10 degrees will be
		/// deleted.
		SppCheck()
			: pDefaultEphemeris(NULL),defaultObservable(TypeID::prefitC),
			PCflag(true), L3flag(false){ };


		/** Returns a satTypeValueMap object, adding the new data generated
		*  when calling a modeling object.
		*
		* @param time      Epoch.
		* @param gData     Data object holding the data.
		*/
		virtual satTypeValueMap& Process( const CommonTime& time,
			satTypeValueMap& gData )
			noexcept(false);



		/** Returns a gnnsRinex object, adding the new data generated when
		*  calling a modeling object.
		*
		* @param gData    Data object holding the data.
		*/
		virtual gnssRinex& Process(gnssRinex& gData)
			noexcept(false)
		{ Process(gData.header.epoch, gData.body); return gData; };



		/// Method to get the default observable for computations.
		virtual TypeID getDefaultObservable() const
		{ return defaultObservable; };


		/** Method to set the default observable for computations.
		*
		* @param type      TypeID object to be used by default
		*/
		virtual SppCheck& setDefaultObservable(const TypeID& type)
		{ defaultObservable = type; return (*this); };


		/// Method to get a pointer to the default XvtStore<SatID> to be used
		/// with GNSS data structures.
		virtual XvtStore<SatID>* getDefaultEphemeris() const
		{ return pDefaultEphemeris; };


		/** Method to set the default XvtStore<SatID> to be used with GNSS
		*  data structures.
		*
		* @param ephem     XvtStore<SatID> object to be used by default
		*/
		virtual SppCheck& setDefaultEphemeris(XvtStore<SatID>& ephem)
		{ pDefaultEphemeris = &ephem; return (*this); };


		// Reset flag for PC or UC
		virtual void setPCFlag(bool flag)
		{ PCflag = flag;};


		// only used in triple frequency
		virtual void setL3Flag(bool flag)
		{ L3flag = flag;};


		/// Returns a string identifying this object.
		virtual std::string getClassName(void) const;


		/// Destructor.
		virtual ~SppCheck() {};


	protected:


		/// Pointer to default XvtStore<SatID> object when working with GNSS
		/// data structures.
		XvtStore<SatID>* pDefaultEphemeris;


		/// Default observable to be used when fed with GNSS data structures.
		/// prefitC/prefitP1 are supported now
		TypeID defaultObservable;


		/// Uncombined or IF combination
		bool PCflag;


		/// L3 flag
		bool L3flag;

	}; // End of class 'SppCheck'

	//@}

}  // End of namespace gpstk

#endif   // GPSTK_SPPCHECK_HPP
